package com.example.black.myapplication.myhandler;

import android.os.Message;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyMessageQueue {
    private int count = 0;
    private static final int MAX_LENTH = 20;
    private Condition notEmpty;
    private Condition notFull;
    private Lock lock;

    public MyMessageQueue() {
        //可重入锁
        this.lock = new ReentrantLock();
        this.notEmpty = lock.newCondition();
        this.notFull = lock.newCondition();
    }

    private MyMessage myMessage;

    public MyMessage next() {
        System.out.println("next" + count);
        MyMessage msg = null;
        try {
            lock.lock();
            while (count == 0) {
               // System.out.println("next 开始 await" + count);
                notEmpty.await();
            }
            msg = myMessage;
            myMessage = msg.next;
            count--;
           // System.out.println("next 结束 await" + count);
            notFull.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();

        } finally {
            lock.unlock();
        }
        return msg;
    }

    public boolean enqueueMessage(MyMessage message) {
        if (message == null || message.target == null) {
            throw new NullPointerException();
        }
       // System.out.println("enqueueMessage" + count);
        try {
            lock.lock();
            while (count == MAX_LENTH) {
                notFull.await();
            }
            if (myMessage == null) {
                myMessage = message;
            } else {
                MyMessage pre = myMessage;
                myMessage = message;
                myMessage.next = pre;
            }
            count++;
         //   System.out.println("enqueueMessage await后" + count);
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();

        } finally {
            lock.unlock();
        }

        return true;
    }
}
